﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WHMS.EntityClasses;
using WMS.HelperClasses;
using WHMS.HelperClasses;
using SD.LLBLGen.Pro.ORMSupportClasses;
using WHMS;

namespace WMS
{
    public partial class frmRetrieveItem : Form
    {
        WithdrawRequestEntity _currentRequest;
        RetrievalTransactionEntity currentRetrievalTransaction;
        WithdrawTransactionEntity _currentWithdrawTransaction;
        DataMngrFormBase<WithdrawRequestItemEntity> _tranItemsForm;
        List<ErrorProvider> _errorProviders;
        int currentProjectId;

        public frmRetrieveItem()
        {
            InitializeComponent();


            _currentRequest = new WithdrawRequestEntity();
            _currentWithdrawTransaction = new WithdrawTransactionEntity();
            currentRetrievalTransaction = new RetrievalTransactionEntity();

            LoadData();

            _errorProviders = new List<ErrorProvider>();

            //this._transItems.EntityFactoryToUse = new WHMS.FactoryClasses.WithdrawRequestItemEntityFactory(); 

            //EnableDisableControls();



        }

        void LoadData()
        {
            //DALHelper.FetchCollection(_removeTypes, null, null, new SortExpression(WithdrawalTypeFields.Order | SortOperator.Ascending));

            //FormsHelper.LoadComboBox(ddlProjects, ProjectFields.Id, ProjectFields.Name, () => Business.GetRunningAndGeneralProjects());
            FormsHelper.LoadComboBox(StoresDDL, StoreFields.Id, StoreFields.Name, () => Business.GetStoresForKeeper());
            //FormsHelper.LoadComboBox(AccountantsDDL, UserFields.Id, UserFields.Name, (x, y) => Business.GetAccountants(x, y));
           // FormsHelper.LoadComboBox(ContractorsDDL, ContractorFields.Id, ContractorFields.Name, (x, y) => DALHelper.GetDynamicList(x, y, null));

            //FormsHelper.CheckStoresAndProjects(StoresDDL.Items, ProjectsDDL.Items, new List<Control>() { _transItemsGrid, SaveBtn }, NoStoresLbl, NoProjectsLbl);
        }

        private EntityCollection<WithdrawTransactionEntity> GetWithdrawTransaction(string withdrawPermitNumber)
        {
            

            var requestTypes = new string[3] { "G", "S", "M" };

            var collection = new EntityCollection<WithdrawTransactionEntity>();
            var filter = new RelationPredicateBucket(TransactionFields.PermitNumber == withdrawPermitNumber);
            filter.Relations.Add(WithdrawTransactionEntity.Relations.TransactionEntityUsingTransactionId);
            filter.PredicateExpression.Add(
                new FieldCompareSetPredicate(WithdrawTransactionFields.Wrnumber, null, WithdrawRequestFields.RequestNumber, null, SetOperator.In, new PredicateExpression(WithdrawRequestFields.Type == requestTypes), false));

            var prefetch = new PrefetchPath2(EntityType.WithdrawTransactionEntity);
            prefetch.Add(WithdrawTransactionEntity.PrefetchPathTransaction);

            DALHelper.FetchCollection(collection, filter, prefetch);

            return collection;
        }

        /// <summary>
        /// Retrieve the retrieval transactions based on the retrieval permit number
        /// </summary>
        /// <param name="retrievalPermitNumber">retrieval permit number</param>
        /// <returns></returns>
        private EntityCollection<RetrievalTransactionEntity> GetRetrievalTransaction(string retrievalPermitNumber)
        {

            var retrievalTransactions = new EntityCollection<RetrievalTransactionEntity>();
            var filter = new RelationPredicateBucket(TransactionFields.PermitNumber == retrievalPermitNumber);
            filter.Relations.Add(RetrievalTransactionEntity.Relations.TransactionEntityUsingTransactionId);
            filter.Relations.Add(RetrievalTransactionEntity.Relations.WithdrawTransactionEntityUsingWithdrawTransactionId);
            
            
            var prefetch = new PrefetchPath2(EntityType.RetrievalTransactionEntity);
            prefetch.Add(RetrievalTransactionEntity.PrefetchPathTransaction);
            prefetch.Add(RetrievalTransactionEntity.PrefetchPathWithdrawTransaction);
            
            
            DALHelper.FetchCollection(retrievalTransactions, filter, prefetch);
            if (retrievalTransactions.Count > 0)
            {
                //to lazy load the transaction object which is inside withdrawal transaction object 
                //which is inside the main retrieval transaction 
                var TransactionOfWithdrawalTransaction = new EntityCollection<TransactionEntity>();
                var transactionFilter = new RelationPredicateBucket(TransactionFields.Id == retrievalTransactions[0].WithdrawTransaction.TransactionId);


                DALHelper.FetchCollection(TransactionOfWithdrawalTransaction, transactionFilter, null);

                retrievalTransactions[0].WithdrawTransaction.Transaction = TransactionOfWithdrawalTransaction[0];
            }
            return retrievalTransactions;
        }

        /// <summary>
        /// Retrieve the retrieval transactions based on the Id of the owned withdrawal transaction 
        /// </summary>
        /// <param name="withdrawTransactionId"></param>
        /// <returns></returns>
        private EntityCollection<RetrievalTransactionEntity> GetRetrievalTransaction(int withdrawTransactionId)
        {


            var retrievalTransactions = new EntityCollection<RetrievalTransactionEntity>();
            var filter = new RelationPredicateBucket(RetrievalTransactionFields.WithdrawTransactionId == withdrawTransactionId);
            filter.Relations.Add(RetrievalTransactionEntity.Relations.TransactionEntityUsingTransactionId);
            filter.Relations.Add(RetrievalTransactionEntity.Relations.WithdrawTransactionEntityUsingWithdrawTransactionId);

            
            var prefetch = new PrefetchPath2(EntityType.RetrievalTransactionEntity);
            prefetch.Add(RetrievalTransactionEntity.PrefetchPathTransaction);
            prefetch.Add(RetrievalTransactionEntity.PrefetchPathWithdrawTransaction);


            DALHelper.FetchCollection(retrievalTransactions, filter, prefetch);

            if (retrievalTransactions.Count > 0)
            {
                //to lazy load the transaction object which is inside withdrawal transaction object 
                //which is inside the main retrieval transaction 
                var TransactionOfWithdrawalTransaction = new EntityCollection<TransactionEntity>();
                var transactionFilter = new RelationPredicateBucket(TransactionFields.Id == retrievalTransactions[0].WithdrawTransaction.TransactionId);


                DALHelper.FetchCollection(TransactionOfWithdrawalTransaction, transactionFilter, null);

                retrievalTransactions[0].WithdrawTransaction.Transaction = TransactionOfWithdrawalTransaction[0];
            }

            return retrievalTransactions;
        }

        private void RetrieveTransaction()
        {
            ResetForm();

            var withdrawalTransactions = new EntityCollection<WithdrawTransactionEntity>();

            var retrievalTransactions = new EntityCollection<RetrievalTransactionEntity>();

           //User need to search for specific retrieval permit number
            if(!string.IsNullOrEmpty(txtRetrievalPermitNumber.Text))
            {
                retrievalTransactions = GetRetrievalTransaction(txtRetrievalPermitNumber.Text);
                if (retrievalTransactions.Count>0)
                withdrawalTransactions.Add(retrievalTransactions[0].WithdrawTransaction);

                if (withdrawalTransactions.Count > 0)
                if(!string.IsNullOrEmpty(withdrawalTransactions[0].Transaction.PermitNumber))
                    txtWithdrawalPermitNumber.Text = withdrawalTransactions[0].Transaction.PermitNumber;
            }
                //User do not saerch based on with drawal transaction 
            else if (!string.IsNullOrEmpty(txtWithdrawalPermitNumber.Text))
            {

                withdrawalTransactions = GetWithdrawTransaction(txtWithdrawalPermitNumber.Text.Trim());

                //if(withdrawalTransactions[0].RetrievalTransactions.Count>0)
                //    txtRetrievalPermitNumber.Text = withdrawalTransactions[0].RetrievalTransactions[0].Transaction.PermitNumber;
            }

            if (withdrawalTransactions.Count <= 0)
            {
               
               
                ResetForm();
            }
            else
            {
                _currentWithdrawTransaction = withdrawalTransactions[0];
                RetrieveRequest(_currentWithdrawTransaction.Wrnumber);

                _WithdrawTransactionBS.DataSource = _currentWithdrawTransaction;
                
                if(_currentWithdrawTransaction.Transaction==null)
                    _TransBS.DataSource = retrievalTransactions[0];
                else
                _TransBS.DataSource = _currentWithdrawTransaction.Transaction;
                


                //I need here to fill info about withdarwal permit like the withDrawen quantity
                var withdrawaltransItems = new EntityCollection<TransactionItemEntity>();

                DALHelper.FetchCollection(withdrawaltransItems, new RelationPredicateBucket(TransactionItemFields.TransactionId == _currentWithdrawTransaction.TransactionId));

                

                foreach (WithdrawRequestItemEntity requestItem in _requestItems)
                {
                    var q = (from t in withdrawaltransItems
                             where t.ItemId == requestItem.ItemId
                             select t).FirstOrDefault();

                    if (q == null)
                        continue;

                    requestItem.NewShelfId = q.ShelfId.Value;
                    requestItem.QuantityToBeWithdrawn = q.Quantity;

                   

                                       

                }

              
                //no retrieval transaction that means you search by withdrawal permit
                //if (retrievalTransactions.Count == 0)
                //    retrievalTransactions = GetRetrievalTransaction(_currentWithdrawTransaction.Id);

                if (retrievalTransactions.Count > 0)
                {
                    if (string.IsNullOrEmpty(txtRetrievalPermitNumber.Text))
                        txtRetrievalPermitNumber.Text = retrievalTransactions[0].Transaction.PermitNumber;

                    //fill retrieval date text box 
                    DTPRetrieve.Value = retrievalTransactions[0].Transaction.Date;

                    var retrievaltransItems = new EntityCollection<TransactionItemEntity>();

                    DALHelper.FetchCollection(retrievaltransItems, new RelationPredicateBucket(TransactionItemFields.TransactionId == retrievalTransactions.First().TransactionId));

                    currentRetrievalTransaction = retrievalTransactions.First();
                    currentRetrievalTransaction.WithdrawTransaction = _currentWithdrawTransaction;
                    
                    foreach (WithdrawRequestItemEntity requestItem in _requestItems)
                    {
                        //var q = (from t in retrievaltransItems
                        //         where t.ItemId == requestItem.ItemId
                        //         select t).FirstOrDefault();

                        //if (q == null)
                        //    continue;
                        
                        //if (!string.IsNullOrEmpty(txtRetrievalPermitNumber.Text))
                        //{
                        //    requestItem.QuantityToBeRetrieved = q.Quantity;
                        //}

                        List<TransactionItemEntity> transactionItems = (from t in retrievaltransItems
                                                                        where t.ItemId == requestItem.ItemId && t.RequestItemId == requestItem.Id
                                                                        select t).ToList();


                        if (transactionItems == null)
                            continue;

                        //orderItem.NewShelfId = q.ShelfId.Value;
                        requestItem.QuantityToBeRetrieved = transactionItems.Sum(t => t.Quantity);



                        if (requestItem.ShelvesBalances == null)
                        {
                            requestItem.ShelvesBalances = LoadShelfBalances(transactionItems);
                        }
                    }
                }
            }

            _WithdrawTransactionBS.DataSource = _currentWithdrawTransaction;
           _TransBS.DataSource = _currentWithdrawTransaction.Transaction;

           
            //Fill ItemName & ItemCode columns in retrieving transaction 
            if (_transItemsGrid.Rows.Count > 0)
            {
                for (int currentRow = 0; currentRow < _transItemsGrid.Rows.Count - 1; currentRow++)
                {
                    _transItemsGrid.Rows[currentRow].Cells[SequenceColumn.Index].Value = currentRow + 1;

                    int productItemId = Int32.Parse(_transItemsGrid.Rows[currentRow].Cells[ItemIdColumn.Index].Value.ToString());
                    GetItemDetailsByItemId(currentRow, productItemId);
                }

            }

            

            EnableDisableControls();
        }

       

        private void ResetForm()
        {
            _currentRequest = new WithdrawRequestEntity();
            _currentWithdrawTransaction = new WithdrawTransactionEntity();
            _currentWithdrawTransaction.Transaction = new TransactionEntity();
            currentRetrievalTransaction = new RetrievalTransactionEntity();

            _WithdrawTransactionBS.DataSource = _currentWithdrawTransaction;
            _TransBS.DataSource = _currentWithdrawTransaction.Transaction;
            _WRequestBS.DataSource = _currentRequest;
            

            DTPRetrieve.Value = DateTime.Now;
            EnableDisableControls();
        }

        private List<ShelfBalance> LoadShelfBalances(List<TransactionItemEntity> transactionItems)
        {
            List<ShelfBalance> shelfbalances = new List<ShelfBalance>();
            foreach (TransactionItemEntity tie in transactionItems)
            {
                shelfbalances.Add(new ShelfBalance() { ShelfId = tie.ShelfId.Value, Quantity = (double)tie.Quantity });
            }
            return shelfbalances;
        }

        private void RetrieveRequest(string requestNumber)
        {
            if (string.IsNullOrEmpty(requestNumber.Trim()))
                return;

            var collection = new EntityCollection<WithdrawRequestEntity>();

            var filter = new RelationPredicateBucket(WithdrawRequestFields.RequestNumber == requestNumber.Trim());

            DALHelper.FetchCollection(collection, filter);

            if (collection.Count <= 0)
            {
                _currentRequest = new WithdrawRequestEntity();
                _WRequestBS.DataSource = _currentRequest;
            }
            else
            {
                _currentRequest = collection[0];
                _WRequestBS.DataSource = _currentRequest;
            }

            
            currentProjectId = _currentRequest.ProjectId;

            LoadRequestItems(_currentRequest.Id);
            LoadShelves(GetStoreId());
            //EnableDisableControls();
        }

        private void LoadRequestItems(int requestId)
        {
            if (_tranItemsForm != null)
            {
                _tranItemsForm.Dispose();
                _tranItemsForm = null;
            }

            var prefetch = new PrefetchPath2(EntityType.WithdrawRequestItemEntity);
            prefetch.Add(WithdrawRequestItemEntity.PrefetchPathItem).SubPath.Add(ItemEntity.PrefetchPathUnit_);

            var label = new Label();
            _tranItemsForm = new DataMngrFormBase<WithdrawRequestItemEntity>(_requestItems, _transItemsGrid, RetrieveTransactionBS, new Button(), label, label, new RelationPredicateBucket(WithdrawRequestItemFields.WithdrawRequestId == requestId), prefetch);
            _tranItemsForm.SetNumericFields(new List<int> { WithdrawQuantityColumn.Index });
            
            _tranItemsForm.RaiseSelectedChangedEventForComboBoxColumns(new List<int> { ShelfColumn.Index });

           // _tranItemsForm.ComboboxColumnSelectionChanged += new DataMngrFormBase<WithdrawRequestItemEntity>.RaiseComboboxColumnSelectionChanged(_tranItemsForm_ComboboxColumnSelectionChanged);
           
            _tranItemsForm.RowValidating += new DataMngrFormBase<WithdrawRequestItemEntity>.RaiseRowValidating(_tranItemsForm_RowValidating);
        }

        private void _tranItemsForm_RowValidating(int rowIndex, ref bool hasErrors)
        {
            var withdrawalQuantityCell = _transItemsGrid.Rows[rowIndex].Cells[WithdrawQuantityColumn.Index];
            var withdrawalQuantity = (withdrawalQuantityCell == null) ? 0 : withdrawalQuantityCell.Value;

            

            var retrievedQuantityCell = _transItemsGrid.Rows[rowIndex].Cells[RetrievedQuantityColumn.Index];
            var retrievedQuantity = retrievedQuantityCell.Value;

            if (retrievedQuantity == null)
                return;

            //if ((decimal)quantity <= 0)
            //{
            //    quantityCell.ErrorText = "الكمية المراد صرفها يجب أن تكون رقم موجب.";
            //    hasErrors = true;
            //    return;
            //}

            if ((withdrawalQuantity != null && (decimal)retrievedQuantity <= (decimal)withdrawalQuantity) )
            {
                retrievedQuantityCell.ErrorText = string.Empty;
                return;
            }


            retrievedQuantityCell.ErrorText = "الكمية المرادارتجاعها يجب أن تكون اكبر من او تساوي الكميه المصروفه سابقا.";
            hasErrors = true;
        }

        #region shelves
        private void LoadShelves(int storeId)
        {
            foreach (DataGridViewRow row in _transItemsGrid.Rows)
            {
                var control = (_transItemsGrid[ShelfComboBoxColumn.Index, row.Index] as DataGridViewComboBoxCell);
                LoadShelves(control, row.Index, storeId);
            }
            WithdrawRequestItemEntity x = new WithdrawRequestItemEntity();
            var index = 0;
            foreach (WithdrawRequestItemEntity item in _requestItems)
            {
                decimal availableQuantity = 0; 
                string shelfCode = string.Empty;
                item.NewShelfId = Business.GetWithdrawShelfId(_currentRequest.ProjectId, storeId, item.ItemId, item.RemainderQuantity, _currentRequest.Type, out availableQuantity, out shelfCode);
               // item.AvailableQantity = availableQuantity;//Diab
                item.AvailableQantity = item.WithdawedQuantity-item.RetrievedQuantity;//Diab
                item.NewShelfCode = shelfCode;
                //_transItemsGrid.CurrentRow.Cells[AvailableAmountColumn.Index].Value = Business.GetItemBalance(_currentRequest.ProjectId, storeId, item.NewShelfId, item.ItemId, _showStoppedProjectsItemsCB.Checked);
                //item.AvailableQantity = Business.GetItemBalance(_currentRequest.ProjectId, storeId, item.NewShelfId, item.ItemId, _showStoppedProjectsItemsCB.Checked);
                _transItemsGrid.Rows[index].Cells[ShelfComboBoxColumn.Index].Value = item.NewShelfCode;
                _transItemsGrid.Rows[index].Cells[ShelfComboBoxColumn.Index].Selected = true;
                _transItemsGrid.Rows[index].Cells[ShelfComboBoxColumn.Index].Selected = false;

                //_transItemsGrid.Rows[index].Cells[AvailableQantityColumn.Index].Value = item.AvailableQantity;
                //_transItemsGrid.Rows[index].Cells[AvailableQantityColumn.Index].Selected = true;
                //_transItemsGrid.Rows[index].Cells[AvailableQantityColumn.Index].Selected = false;
                index++;
            }

            if (_transItemsGrid.Rows.Count > 0)
                _transItemsGrid.Rows[0].Cells[WithdrawQuantityColumn.Index].Selected = true;
        }
        
        private void LoadShelves(DataGridViewComboBoxCell control, int rowIndex, int storeId)
        {
            var itemIdValue = _transItemsGrid.Rows[rowIndex].Cells[ItemIdColumn.Index].Value;
            if (itemIdValue == null)
                return;

            control.DisplayMember = ShelfFields.Code.Name;
            control.ValueMember = ShelfFields.Id.Name;

            var shelves = GetShelves((int)itemIdValue, storeId);
            var bindingsource = new BindingSource();
            bindingsource.DataSource = shelves;
            control.DataSource = bindingsource;

            if (shelves.Count <= 0)
            {
                //MessageBox.Show("لا يوجد رصيد بالمخزن المختار", "تنبيه", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                _transItemsGrid.Rows[rowIndex].Cells[ShelfColumn.Index].ErrorText = "لا يوجد رصيد بالمخزن";
            }
            else
            {
                _transItemsGrid.Rows[rowIndex].Cells[ShelfColumn.Index].ErrorText = string.Empty;
            }
        }

        private void GetShelves()
        {
            var storeId = GetSelectedStoreId();
            _shelves.Clear();
            DALHelper.FetchCollection(_shelves, new RelationPredicateBucket(ShelfFields.StoreId == storeId));
        }
        
        private EntityCollection<ShelfEntity> GetShelves(int itemId, int storeId)
        {
            var filter = GetShelvesFilter(itemId, storeId);


            var shelves = new EntityCollection<ShelfEntity>();
            DALHelper.FetchCollection(shelves, filter);
            return shelves;
        }

        private RelationPredicateBucket GetShelvesFilter(int itemId, int storeId)
        {
            var shelfFilter = new PredicateExpression(StoreShelfBalanceFields.ItemId == itemId);
            shelfFilter.Add(StoreShelfBalanceFields.StoreId == storeId);

            var projectFilter = new PredicateExpression(StoreShelfBalanceFields.ProjectId == currentProjectId);
            //if (_showStoppedProjectsItemsCB.Checked)
            //{
            //    projectFilter.AddWithOr(new FieldCompareSetPredicate(StoreShelfBalanceFields.ProjectId, null, ProjectFields.Id, null, SetOperator.In, new PredicateExpression(ProjectFields.Status == "جارى"), true));
            //    projectFilter.AddWithOr(new FieldCompareSetPredicate(StoreShelfBalanceFields.ProjectId, null, ProjectFields.Id, null, SetOperator.In, new PredicateExpression(ProjectFields.IsGeneral == true)));
            //}
            shelfFilter.Add(projectFilter);

            var filter = new RelationPredicateBucket(new FieldCompareSetPredicate(ShelfFields.Id, null, StoreShelfBalanceFields.ShelfId, null, SetOperator.In, shelfFilter));
            filter.PredicateExpression.Add(ShelfFields.StoreId == storeId);
            return filter;
        }

        #endregion

        //private int GetSelectedProjectId()
        //{
        //    return 0;//(int)((System.Data.DataRowView)(ddlProjects.SelectedItem)).Row.ItemArray[0];
        //}

        private int GetSelectedStoreId()
        {
            var storeId = (int)((System.Data.DataRowView)(StoresDDL.SelectedItem)).Row.ItemArray[0];
            return storeId;
        }		
        private int GetStoreId()
        {
            if (_currentWithdrawTransaction.Transaction == null)
            {
                if (StoresDDL.SelectedItem == null)
                    return 0;

                return (int)((System.Data.DataRowView)(StoresDDL.SelectedItem)).Row.ItemArray[0];
            }

            if (_currentWithdrawTransaction.Transaction.StoreId.HasValue)
                return _currentWithdrawTransaction.Transaction.StoreId.Value;

            return 0;
        }

        /// <summary>
        /// Retrieve the data table represent item(Product) details based on ItemId
        /// Added by Thabet
        /// </summary>
        /// <param name="rowIndex"> Index of row in data grid</param>
        /// <param name="itemId">The ID of item(Product)</param>
        private void GetItemDetailsByItemId(int rowIndex, int itemId)
        {
            DataTable itemDT = Business.GetItemDetails(itemId);
            if (itemDT.Rows.Count <= 0)
                return;

            _transItemsGrid.Rows[rowIndex].Cells[ItemCodeColumn.Index].Value = itemDT.Rows[0][0].ToString();
            _transItemsGrid.Rows[rowIndex].Cells[ItemNameColumn.Index].Value = itemDT.Rows[0][1].ToString();

            _transItemsGrid.Rows[rowIndex].Cells[ItemIdColumn.Index].Value = itemId;

            return;
        }

        

        private void btnSave_Click(object sender, EventArgs e)
        {
            Save();

        }

        private void Save()
        {
            if (!ValidateForm())
                return;


            var transItems = new EntityCollection<TransactionItemEntity>();
            var transItemsToDelete = new EntityCollection<TransactionItemEntity>();

           
            if(!currentRetrievalTransaction.IsNew)
            {
                //if ((bool)DALHelper.GetValue(RetrievalTransactionFields.TransactionId, RetrievalTransactionFields.Id, currentRetrievalTransaction.Id))
                //{

                
                   // RetrieveTransaction();
                    DALHelper.FetchCollection(transItems, new RelationPredicateBucket(TransactionItemFields.TransactionId == currentRetrievalTransaction.TransactionId));
            
                //    return;
                //}
            }
            else
            {
                //check if the retrieval permit number is used before 
                if (GetRetrievalTransaction(txtRetrievalPermitNumber.Text).Count > 0)
                {

                    MessageBox.Show("رقم اذن الإرتجاع مستخدم من قبل", "خطأ فى الحفظ", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;

                }

                currentRetrievalTransaction.WithdrawTransaction = GetWithdrawTransaction(txtWithdrawalPermitNumber.Text)[0];
                
                //AccountantId = _currentRequest.AccountantId;
                //_currentWithdrawTransaction.ContractorId = _currentRequest.ContractorId;
                //_currentWithdrawTransaction.Wrnumber = _currentRequest.RequestNumber;
                //_currentWithdrawTransaction.Type = _currentRequest.Type;
                currentRetrievalTransaction.Recipient = txtRecipient.Text;

                var transaction = new TransactionEntity()
                {
                    ProjectId = _currentRequest.ProjectId,
                    StoreId = GetSelectedStoreId(),
                    PermitNumber = txtRetrievalPermitNumber.Text,
                    CreatedBy = UserInfo.UserId,
                    Date = DTPRetrieve.Value.Date,
                    Type = "Retrieve",
                };

                //_currentWithdrawTransaction.Transaction = transaction;
                currentRetrievalTransaction.Transaction = transaction;
            }
          

           
                foreach (WithdrawRequestItemEntity item in _requestItems)
                {
                    if ((item.NewShelfId > 0)&&(item.QuantityToBeRetrieved>0))
                    {
                        var q = (from t in transItems
                                 where t.RequestItemId == item.Id
                                 select t).FirstOrDefault();

                        TransactionItemEntity transItem;

                        if (q == null)
                        {
                            transItem = new TransactionItemEntity();
                        }
                        else
                        {
                            transItem = q;
                        }

                        //I need not only item that has action retrieved so I make the following check as I do not need to
                        //add much data at transaction table
                        if (item.QuantityToBeRetrieved != 0)
                        {

                            transItem.ShelfId = item.NewShelfId;
                            transItem.StoreId = _currentWithdrawTransaction.Transaction.StoreId.Value;
                            transItem.ItemId = item.ItemId;
                            transItem.Quantity = item.QuantityToBeRetrieved;
                            transItem.RequestItemId = item.Id;
                            transItem.MoveType = "RT";



                            // var price = Business.GetItemPrice(_currentRequest.ProjectId, transItem.StoreId, item.NewShelfId, item.ItemId);
                            //transItem.UnitPrice = price;
                            // transItem.SellingPrice = price;// Business.GetItemCost(transItem.StoreId, transItem.ShelfId.Value, transItem.ItemId);

                            // _currentWithdrawTransaction.Transaction.TransactionItems.Add(transItem);
                            currentRetrievalTransaction.Transaction.TransactionItems.Add(transItem);
                        }
                    }
                    //if (item.QuantityToBeRetrieved > 0)
                    //{
                    //    List<TransactionItemEntity> transactionItems = (from t in transItems
                    //             where t.RequestItemId == item.Id
                    //             select t).ToList();

                    //    if (item.ShelvesBalances == null || item.ShelvesBalances.Count == 0)
                    //    {
                    //        item.ShelvesBalances = LoadShelfBalances(transactionItems);
                    //    }
                        

                    //    int index = 0;
                    //    //Loop for all shelves contain items 
                    //    foreach (ShelfBalance shelfBalance in item.ShelvesBalances)
                    //    {
                            
                    //        TransactionItemEntity transItem = new TransactionItemEntity();

                    //        if (transactionItems == null)
                    //        {

                    //            //item.DeliveredQuantity += item.QuantityToBeAdded;


                    //        }
                    //        else if (transactionItems.Count > 0)
                    //        {
                    //            if (transactionItems.Count > index)
                    //                transItem = transactionItems[index];
                    //            else
                    //                transItem = new TransactionItemEntity();

                    //            // item.DeliveredQuantity += ((decimal)shelfBalance.Quantity - transItem.Quantity);

                    //        }

                    //        //item.LastDeliveryDate = AdditionDateDTP.Value.Date;

                    //        //I need not only item that has action retrieved so I make the following check as I do not need to
                    //        //add much data at transaction table
                    //        if (item.QuantityToBeRetrieved != 0)
                    //        {

                    //            transItem.ShelfId = item.NewShelfId;
                    //            transItem.StoreId = _currentWithdrawTransaction.Transaction.StoreId.Value;
                    //            transItem.ItemId = item.ItemId;
                    //            //transItem.Quantity = item.QuantityToBeRetrieved;
                    //            transItem.Quantity = (decimal)shelfBalance.Quantity;
                    //            transItem.RequestItemId = item.Id;
                    //            transItem.MoveType = "RT";


                    //            currentRetrievalTransaction.Transaction.TransactionItems.Add(transItem);
                    //        }
                    //        index++;
                    //    }
                    //}
                    else
                    {
                        var q = (from t in transItems
                                 where t.RequestItemId == item.Id
                                 select t).FirstOrDefault();

                        if (q != null)
                        {
                            transItemsToDelete.Add(q);
                        }
                    }
                }

                DALHelper.DeleteCollection(transItemsToDelete);
                //if (DALHelper.SaveEntity(_currentWithdrawTransaction, true))
                if (DALHelper.SaveEntity(currentRetrievalTransaction, true))
                {
                    _currentRequest.IsApproved = true;
                    DALHelper.SaveEntity(_currentRequest);
                    DALHelper.SaveCollection(_requestItems);



                    RetrieveTransaction();
                    MessageBox.Show("تم الحفظ بنجاح.");
                }
            
        }

        private bool ValidateForm()
        {
            var isValid = true;

            var controls = new List<TextBox>();
            controls.Add(txtRecipient);
            controls.Add(txtRetrievalPermitNumber);
            controls.Add(txtWithdrawalPermitNumber);

            if (_errorProviders == null)
            {
                _errorProviders = new List<ErrorProvider>();
            }
            else
            {
                foreach (var errorProvider in _errorProviders)
                {
                    errorProvider.Clear();
                    errorProvider.Dispose();
                }
            }
            foreach (var tb in controls)
            {
                if (string.IsNullOrEmpty(tb.Text.Trim()))
                {
                    var errorProvider = new ErrorProvider(this);
                    _errorProviders.Add(errorProvider);

                    errorProvider.SetError(tb, "يجب إدخال قيمة");
                    errorProvider.RightToLeft = true;

                    isValid = false;
                    continue;
                }
            }

            //if (!ValidatePermitNumber())
            //    isValid = false;

            //_tranItemsForm.ValidateCollection();
            if (!_tranItemsForm.IsDataValid())
                isValid = false;

            if (_requestItems.Count <= 0)
            {
                isValid = false;
                MessageBox.Show("يجب إضافة أصناف", "خطأ فى الحفظ", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            
            return isValid;
        }

        private void btnSearchWithdrawalPermit_Click(object sender, EventArgs e)
        {

            var requestTypes = new string[3] { "G", "S", "M" };

            var filter = new RelationPredicateBucket(TransactionFields.Type == "Withdraw");
            filter.Relations.Add(TransactionEntity.Relations.ProjectEntityUsingProjectId);
            filter.Relations.Add(TransactionEntity.Relations.WithdrawTransactionEntityUsingTransactionId);

            filter.PredicateExpression.Add(
                new FieldCompareSetPredicate(WithdrawTransactionFields.Wrnumber, null, WithdrawRequestFields.RequestNumber, null, SetOperator.In, new PredicateExpression(WithdrawRequestFields.Type == requestTypes), false));

            var searchForm = new SearchForm(TransactionFields.PermitNumber, TransactionFields.ProjectId, TransactionFields.Date, filter, null);
            if (searchForm.ShowDialog() == DialogResult.OK)
            {
                txtWithdrawalPermitNumber.Text = searchForm.SelectedNumber;
                txtRetrievalPermitNumber.Text = string.Empty;
                RetrieveTransaction();
            }
        }

        private void btnRetrieveWithdrawalPermit_Click(object sender, EventArgs e)
        {
            RetrieveTransaction();

        }

        private void btnSearchRetrievalPermit_Click(object sender, EventArgs e)
        {
            var filter = new RelationPredicateBucket(TransactionFields.Type == "Retrieve");
            filter.Relations.Add(TransactionEntity.Relations.ProjectEntityUsingProjectId);
            //filter.Relations.Add(TransactionEntity.Relations.WithdrawTransactionEntityUsingTransactionId);

            //filter.PredicateExpression.Add(
            //    new FieldCompareSetPredicate(WithdrawTransactionFields.Wrnumber, null, WithdrawRequestFields.RequestNumber, null, SetOperator.In, new PredicateExpression(WithdrawRequestFields.Type == requestTypes), false));

            var searchForm = new SearchForm(TransactionFields.PermitNumber, TransactionFields.ProjectId, TransactionFields.Date, filter, null);
            if (searchForm.ShowDialog() == DialogResult.OK)
            {
                txtRetrievalPermitNumber.Text = searchForm.SelectedNumber;

                RetrieveTransaction();
            }
        }

        private void btnRetrieveRetrievalPermit_Click(object sender, EventArgs e)
        {
            RetrieveTransaction();
        }

        private void NewBtn_Click(object sender, EventArgs e)
        {
            txtRetrievalPermitNumber.Text = string.Empty;
            ResetForm();
            RetrieveTransaction();
        }

        private void btnFinallySave_Click(object sender, EventArgs e)
        {
            var form = new SaveConfirmationForm();

            if (form.ShowDialog() == DialogResult.Yes)
            {
                
                Save();
                currentRetrievalTransaction.TransactionStatus = 1;
                EnableDisableControls();

                //Update withedarawl request items (add retrieval quantity & update the availbal balnace)
                foreach (WithdrawRequestItemEntity item in _requestItems)
                {
                    
                    

                    item.RetrievedQuantity += item.QuantityToBeRetrieved;

                    item.AvailableQantity = item.WithdawedQuantity - item.RetrievedQuantity;

                    DALHelper.SaveEntity(item);
                }

                Business.StoreItems(GetSelectedStoreId(),currentRetrievalTransaction,currentRetrievalTransaction.Transaction);
            }
        }



        void EnableDisableControls()
        {
            if (currentRetrievalTransaction.TransactionStatus == 1)
            {
                lblRetrievalTransactionMsg.Text = "* إذن الإرتجاع تم حفظه نهائيا ولا يمكن تغيير بياناته  !";
            }
            else
            {
                lblRetrievalTransactionMsg.Text = string.Empty;
            }



            bool isFinnalySaved = currentRetrievalTransaction.TransactionStatus > 0;

          

            _transItemsGrid.Enabled = !isFinnalySaved;// !isPriced;
            btnSave.Enabled = !isFinnalySaved;// !isPriced;
            btnFinallySave.Enabled = !isFinnalySaved;
            bindingNavigator1.Enabled = !isFinnalySaved;//!isPriced;
            lblRetrievalTransactionMsg.Visible = isFinnalySaved;
            StoresDDL.Enabled = !isFinnalySaved;//!isPriced;

            //WithdrawlDateDTP.Enabled = isEditable;//!isPriced;
            //_showStoppedProjectsItemsCB.Enabled = isEditable;//!isPriced;

            NewBtn.Enabled = !_currentWithdrawTransaction.IsNew;
            //DeleteBtn.Enabled = !_currentWithdrawTransaction.IsNew && isFinnalySaved;

            //_showStoppedProjectsItemsCB.Checked = (_currentRequest.Type == "G");
            //_showStoppedProjectsItemsCB.Enabled = (_currentRequest.Type != "G");
        }

        private void _transItemsGrid_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex == columnQuantityToBeRetrieved.Index)
            {
                if (!ValidateForm())
                    return;

                double availableBalance = Double.Parse(_transItemsGrid.Rows[e.RowIndex].Cells[AvailableQantityColumn.Index].Value.ToString());
                int itemId = Int32.Parse(_transItemsGrid.Rows[e.RowIndex].Cells[ItemIdColumn.Index].Value.ToString());

                if (_transItemsGrid.Rows[e.RowIndex].Cells[columnQuantityToBeRetrieved.Index].Value.ToString() == "0")
                {

                    //ShelfBalanceForm shelfBalanceFrm = new ShelfBalanceForm(GetSelectedStoreId(), itemId, availableBalance, _currentTransaction.Id);
                    ShelfBalanceForm shelfBalanceFrm = new ShelfBalanceForm(GetSelectedStoreId(), itemId, availableBalance, ((TransactionEntity)_TransBS.DataSource).Id);
                    
                    shelfBalanceFrm.ShowDialog();


                    _transItemsGrid.Rows[e.RowIndex].Cells[columnQuantityToBeRetrieved.Index].Value = shelfBalanceFrm.allItemsShelvesBalancesValue.ToString();

                    ((WithdrawRequestItemEntity)_requestItems[e.RowIndex]).ShelvesBalances = shelfBalanceFrm.ItemShelvesBalances;
                }
                else
                {
                    ShelfBalanceForm shelfBalanceFrm = new ShelfBalanceForm(((WithdrawRequestItemEntity)_requestItems[e.RowIndex]).ShelvesBalances, availableBalance, GetSelectedStoreId());
                    shelfBalanceFrm.ShowDialog();

                    _transItemsGrid.Rows[e.RowIndex].Cells[columnQuantityToBeRetrieved.Index].Value = shelfBalanceFrm.allItemsShelvesBalancesValue.ToString();

                    ((WithdrawRequestItemEntity)_requestItems[e.RowIndex]).ShelvesBalances = shelfBalanceFrm.ItemShelvesBalances;
                }

            }
        }

       
    }
}
